;(function (root, document, jQuery, factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD
        console.log("amd");
        define(['jquery'], factory(root, document, jQuery)); // requireJs在当前目录引入jquery
    } else if (typeof exports === 'object') {
        // Node/CommonJS.
        console.log("commonJs");
        module.exports = factory(root, document, jQuery);
    } else {
        // 浏览器(Browser globals)
        console.log("browser");
        factory(root, document, jQuery);
    }
    // 匿名函数 (function 作为参数) , root 是根对象: JS 是window , nodeJS 是 global
})(typeof global !== "undefined" ? global : this.window || this.global, document, jQuery, function (root, document, $, undefined) {

    // 验证是否引用jquery
    if (!root.jQuery) {
        alert('请先引入jQuery,再使用class-schedule');
        return;
    }

    var doc = document, $root = $(root), pluginName = "classSchedule";


    // 默认参数
    /**
     * 1 分成3个容器展示: "年份切换","月份","日期"
     * */
    var DEFAULTS = {
        eleYear: "#eleYear",
        eleMonth: "#eleMonth",
        eleDay: "#eleDay",


    };

    // 合并后的参数
    var opt = {};

    var ClassSchedule = function (options) {
        opt = $.extend({}, DEFAULTS, options);
        /**
         * 1 本月第一天是星期几: 1 号放在哪个位置
         * 2 上个月有多少天: 如果是一月份, 就要算去年的12月
         * 3 上个月最后N天是什么: 用于日历前面的补位
         * 4 本月最后一天是星期几: 用于补下个月的天数
         * */
        var obj = {
            calendar: "",
            init: function () {
                this.createYear();
                this.createMonth();
                this.createDay();
                this.initDate();
            },
            // 1 ========= 基本元素生成 "年,月,日 =========="

            // 1.1 年份生成
            createYear: function () {
                var year = $("<div class='year-setting'>" +
                    "<span class='minus glyphicon glyphicon-chevron-left'></span>" +
                    "<span class='year-num'>2018</span>" +
                    "<span class='plus glyphicon glyphicon-chevron-right'></span>" +
                    "</div>");

                var minus = year.find(".minus");
                var plus = year.find(".plus");
                var num = year.find(".year-num");

                // 年份减
                minus.on("click", function () {
                    console.log("minus");
                    var text = Number(num.text());
                    num.text(--text);
                });

                // 年份加
                plus.on("click", function () {
                    var text = Number(num.text());
                    num.text(++text);
                });

                $(opt.eleYear).append(year);
            },
            // 1.2 月份生成
            createMonth: function () {
                var month = $("<div class='month-setting'>" +
                    "<div class='month-item'>一月份</div>" +
                    "<div class='month-item'>二月份</div>" +
                    "<div class='month-item'>三月份</div>" +
                    "<div class='month-item'>四月份</div>" +
                    "<div class='month-item'>五月份</div>" +
                    "<div class='month-item'>六月份</div>" +
                    "<div class='month-item'>七月份</div>" +
                    "<div class='month-item'>八月份</div>" +
                    "<div class='month-item'>九月份</div>" +
                    "<div class='month-item'>十月份</div>" +
                    "<div class='month-item'>十一月份</div>" +
                    "<div class='month-item'>十二月份</div>" +
                    "</div>");

                var item = month.find(".month-item");
                item.on("click", function () {
                    $(this).addClass("month-active").siblings().removeClass("month-active");

                });
                $(opt.eleMonth).append(month);
            },
            // 1.3 日期生成
            createDay: function () {
                var _this = this;
                var table = $('<div class="right-table"><table class="table">' +
                    '<thead>' +
                    '<th>一</th>' +
                    '<th>二</th>' +
                    '<th>三</th>' +
                    '<th>四</th>' +
                    '<th>五</th>' +
                    '<th>六</th>' +
                    '<th>七</th>' +
                    '</thead>' +
                    '<tbody></tbody>' +
                    '</table></div>');

                var tbody = table.find("tbody");

                var firstDay = _this.getFirstDay(); // 本月第一天是星期几



                var tr = $(
                    '<tr>' +
                    '<td><span>1</span></td>' +
                    '<td><span>2</span></td>' +
                    '<td><span>3</span></td>' +
                    '<td><span>4</span></td>' +
                    '<td><span>5</span></td>' +
                    '<td><span>6</span></td>' +
                    '<td><span>7</span></td>' +
                    '</tr>');


                $(opt.eleDay).find("span").on("click", function () {
                    console.log("call");
                    $(this).toggleClass("day-remove");
                });
            },

            // 2 ========= 判断闰年 (leapYear) ==============
            leapYear: function (_year) {
                // 闰年: 2月份为29天 , 正常28天
                // 计算: 能被400 整除, 或者 能被4整除却不能被100整除
                if (_year % 400 === 0 || (_year % 4 === 0 && _year % 100 !== 0)) {
                    return true;
                }
                return false;
            },

            // 3 ========== 判断某年某月的1号是星期几 ========
            getFirstDay: function (_year, _month) {
                var _this = this;
                var allDay = 0, y = _year - 1, i = 1;

                // 得出一年有多少天
                allDay = y + Math.floor(y / 4) - Math.floor(y / 100) + Math.floor(y / 400) + 1;
                console.log("year: ",_year); // 2018
                console.log("month: ",_month); // 7
                console.log("allDay: ",allDay); // 2507
                
                for (; i < _month; i++) {
                    switch (i) {
                        case 1:
                            allDay += 31;
                            break;
                        case 2:
                            if (_this.leapYear(_year)) allDay += 29; else allDay += 28;
                            break;
                        case 3:
                            allDay += 31;
                            break;
                        case 4:
                            allDay += 30;
                            break;
                        case 5:
                            allDay += 31;
                            break;
                        case 6:
                            allDay += 30;
                            break;
                        case 7:
                            allDay += 31;
                            break;
                        case 8:
                            allDay += 31;
                            break;
                        case 9:
                            allDay += 30;
                            break;
                        case 10:
                            allDay += 31;
                            break;
                        case 11:
                            allDay += 30;
                            break;
                        case 12:
                            allDay += 31;
                            break;
                    }
                }
                return allDay % 7 || 7;

                /*
                W = （[C/4] - 2C + y + [y/4] + [13 * (M+1) / 5] + d - 1 ）%7

                w：星期； w对7取模得：0-星期日，余数是几就是星期几。
                c：世纪减1（年份前两位数）
                y：年（后两位数）
                m：月（m大于等于3，小于等于14，即在蔡勒公式中，某年的1、2月要看作上一年的13、14月来计算）
                d：日
                */

            },
            getFirstDay2: function (_year, _month) {
                var _this = this;
                var allDay = 0, y = _year - 1, i = 1;

                // 得出一年有多少天
                allDay = y + Math.floor(y / 4) - Math.floor(y / 100) + Math.floor(y / 400) + 1;
                console.log("year: ",_year); // 2018
                console.log("month: ",_month); // 7
                console.log("allDay: ",allDay); // 2507

                for (; i < _month; i++) {
                    switch (i) {
                        case 1:
                            allDay += 31;
                            break;
                        case 2:
                            if (_this.leapYear(_year)) allDay += 29; else allDay += 28;
                            break;
                        case 3:
                            allDay += 31;
                            break;
                        case 4:
                            allDay += 30;
                            break;
                        case 5:
                            allDay += 31;
                            break;
                        case 6:
                            allDay += 30;
                            break;
                        case 7:
                            allDay += 31;
                            break;
                        case 8:
                            allDay += 31;
                            break;
                        case 9:
                            allDay += 30;
                            break;
                        case 10:
                            allDay += 31;
                            break;
                        case 11:
                            allDay += 30;
                            break;
                        case 12:
                            allDay += 31;
                            break;
                    }
                }
                return allDay % 7;

                /*
                W = （[C/4] - 2C + y + [y/4] + [13 * (M+1) / 5] + d - 1 ）%7

                w：星期； w对7取模得：0-星期日，余数是几就是星期几。
                c：世纪减1（年份前两位数）
                y：年（后两位数）
                m：月（m大于等于3，小于等于14，即在蔡勒公式中，某年的1、2月要看作上一年的13、14月来计算）
                d：日
                */

            },

            
            // 4 ========== 创建日历表格,显示日历 ============
            showCalendar: function (_year, _month, _day, firstDay) {
                var _this = this;
                var i = 0,
                    monthDay = 0,
                    showStr = "",
                    _classname = "",
                    today = new Date();
                //月份的天数
                switch (_month) {
                    case 1:
                        monthDay = 31;
                        break;
                    case 2:
                        if (_this.leapYear(_year)) {
                            monthDay = 29;
                        }
                        else {
                            monthDay = 28;
                        }
                        break;
                    case 3:
                        monthDay = 31;
                        break;
                    case 4:
                        monthDay = 30;
                        break;
                    case 5:
                        monthDay = 31;
                        break;
                    case 6:
                        monthDay = 30;
                        break;
                    case 7:
                        monthDay = 31;
                        break;
                    case 8:
                        monthDay = 31;
                        break;
                    case 9:
                        monthDay = 30;
                        break;
                    case 10:
                        monthDay = 31;
                        break;
                    case 11:
                        monthDay = 30;
                        break;
                    case 12:
                        monthDay = 31;
                        break;
                }

                //输出日历表格，这部分因结构而异
                showStr = "<table class='cld-w'><thead>";

                //日历头部
                showStr += "<tr><th colspan='7'><div class='cld-hd'><span class='cld-pre'>&lt;</span><em id='showDate' value='" + _year + "-" + _month + "-" + _day + "'>" + _year + "年" + _month + "月" + _day + "日" + "</em><span class='cld-next'>&gt;</span></div></th></tr>";

                //日历星期
                showStr += "<tr><th>日</th><th>一</th><th>二</th><th>三</th><th>四</th><th>五</th><th>六</th></tr>";
                showStr += "</thead><tbody><tr>";
                //当月第一天前的空格
                for (i = 1; i <= firstDay; i++) {
                    showStr += "<td></td>";
                }
                //显示当前月的天数
                for (i = 1; i <= monthDay; i++) {
                    //当日的日期
                    if (_year === today.getFullYear() && _month === today.getMonth() + 1 && i === today.getDate()) {
                        _classname = "cld-cur";
                    }
                    //当日之前的日期（这个判断是因为我有工作需求，就是要求之前的日期不能点击）
                    else if (_year < today.getFullYear() || (_year === today.getFullYear() && _month <= today.getMonth()) || (_year === today.getFullYear() && _month === today.getMonth() + 1 && i < today.getDate())) {
                        _classname = "cld-old";
                    }
                    //其他普通的日期
                    else {
                        _classname = "cld-day";
                    }
                    //其他大于当月的月份的相同日期（为了让点击下一月的时候，相同的日期增加cld-cur类）
                    if (_day === i && (_year > today.getFullYear() || _month > today.getMonth() + 1)) {
                        _classname = "cld-cur";
                    }
                    //把日期存在对应的value
                    showStr += "<td class=" + _classname + " value='" + _year + "-" + _month + "-" + i + "'>" + i + "</td>";

                    firstDay = (firstDay + 1) % 7;
                    if (firstDay === 0 && i !== monthDay) {
                        showStr += "</tr><tr>";
                    }
                }

                //剩余的空格
                if (firstDay !== 0) {
                    for (i = firstDay; i < 7; i++) {
                        showStr += "<td></td>";
                    }
                }

                showStr += "</tr></tbody></table>";
                //插入calendar的页面结构里
                _this.calendar.innerHTML = showStr;
            },

            // 5 ========== 在日历头部显示年月日 ===================
            showDate: function (_year, _month, _day) {

                var date = "", firstDay = this.getFirstDay(_year, _month, _day);
                if (_day !== 0) {
                    date = _year + "年" + _month + "月" + _day + "日";
                }
                else {
                    date = "No Choose.";
                }
                document.getElementById("showDate").innerHTML = date; //日历头部显示
                this.showCalendar(_year, _month, _day, firstDay);         //调用日历显示函数
            },

            // 6 ========== 上一月 和 下一月 ======================

            // 6.1 上一月
            preMonth: function (_year, _month, _day) {
                if (_month == 1) {
                    this.showDate(_year - 1, 12, _day);
                }
                else {
                    this.showDate(_year, _month - 1, _day);
                }
            },

            // 6.2 下一月
            nextMonth: function (_year, _month, _day) {
                if (_month == 12) {
                    this.showDate(_year + 1, 1, _day);
                }
                else {
                    this.showDate(_year, _month + 1, _day);
                }
            },


            // 7 =========== 初始化，日历就出来了 ===================
            initDate: function () {
                var _this = this;
                //初始化
                var calendar = document.createElement('div');
                this.calendar = calendar;

                calendar.setAttribute('id', 'showCld');
                // document.getElementById("box").appendChild(calendar); //增加到你的box里
                $(opt.eleDay).append(calendar); //增加到你的box里

                //获取当天的年月日
                var today = new Date();
                var _year = today.getFullYear(),
                    _month = today.getMonth() + 1,
                    _day = today.getDate();
                var firstDay = this.getFirstDay(_year, _month);

                console.log("这个月的1号是星期",firstDay);
                //显示日历
                _this.showCalendar(_year, _month, _day, firstDay);

                // 8 ============ 日历的点击事件 ===============

                //日历点击的事件委托（可以查查js冒泡的应用）
                calendar.onclick = function (e) {
                    var e = e || window.event;
                    var target = e.srcElement || e.target;
                    //把日历的头部的年月日分割成数组，这里保存在其value属性上
                    dayArr = document.getElementById('showDate').getAttribute('value').split('-');
                    if (target) {
                        //如果是可点击的日期
                        if (target.className === "cld-day" || target.className === "cld-cur") {
                            dateArr = target.getAttribute('value').split('-');
                            //减0是把字符串转化成数值类型，以下一样
                            showDate(dateArr[0] - 0, dateArr[1] - 0, dateArr[2] - 0);
                            calendar.className = "";
                        }
                        //如果是上一月的点击
                        else if (target.className === "cld-pre") {
                            _this.preMonth(dayArr[0] - 0, dayArr[1] - 0, dayArr[2] - 0);
                        }
                        //如果是下一月的点击
                        else if (target.className === "cld-next") {
                            _this.nextMonth(dayArr[0] - 0, dayArr[1] - 0, dayArr[2] - 0);
                        }
                    }
                };

            }

        };

        obj.init();

        // this.each(function () {
        //     if (!$.data(this, "plugin_" + pluginName)) {
        //         // 传进去的this 是each 出来的原生js对象
        //         $.data(this, "plugin_" + pluginName, new DateTime(this, options));
        //     }
        // });

        // this 是jquery 对象
        return this;
    };


    // 给jQuery 扩展方法
    $.fn[pluginName] = ClassSchedule;
});
